<?php

/**
 *  This file is part of Urd.
 *
 *  Urd is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *  Urd is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. See the file "COPYING". If it does not 
 *  exist, see <http://www.gnu.org/licenses/>.
 * 
 * $LastChangedDate: 2008-12-22 00:28:59 +0100 (Mon, 22 Dec 2008) $
 * $Rev: 358 $
 * $Author: gavinspearhead $
 * $Id: queue_functions.php 358 2008-12-21 23:28:59Z gavinspearhead $
 */

if (!defined('ORIGINAL_PAGE')) die('This file cannot be accessed directly.');

$pathqf = realpath(dirname(__FILE__));

require_once "$pathqf/../functions/autoincludes.php";
require_once "$pathqf/../functions/urdversion.php";
require_once "$pathqf/../functions/defines.php";
require_once "$pathqf/../config.php";
require_once "$pathqf/../functions/functions.php";
require_once "$pathqf/urdd_command.php";
require_once "$pathqf/urdd_protocol.php";
require_once "$pathqf/urdd_error.php";
require_once "$pathqf/../functions/urd_log.php";


function queue_generic(DatabaseConnection $db, server_data &$servers, $username, $command, $arg, $needs_nntp, $priority=DEFAULT_PRIORITY, $preferred_server_only=FALSE, $restart = TRUE, $paused=FALSE)
{
    assert(is_numeric($priority) && is_bool($preferred_server_only) && $username != '' && is_bool($restart));
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    global $responses;
    try {
        $item = new action($command, $arg, $username, $paused);
    } catch (exception $e) {
        return $responses[500]; // should not happen....
    }
    if ($servers->has_equal($item))
        $response = $responses[403];
    else {
        $res = $servers->queue_push($db, $item, TRUE, QUEUE_BOTTOM, $priority);
        if ($restart === FALSE)
            update_queue_norestart($db, $item->get_dbid());

        if ($res !== FALSE)
            $response = sprintf($responses[201], $item->get_id());
        else 
            $response = $responses[402];
    }
    return $response;
}


function queue_adddata(DatabaseConnection $db, server_data &$servers, $arg_list, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    global $responses;
    $preview = FALSE; 
    // TODO set database/servers to lock download
    if (is_numeric($arg_list[0]) && isset($arg_list[1]) && isset($arg_list[2])) {
        $item = new action(COMMAND_ADDDATA, implode (' ', $arg_list), $username);
        if ((isset($arg_list[3]) && strtolower($arg_list[3]) == 'preview') || (isset($arg_list[4]) && strtolower($arg_list[4]) == 'preview')) {
            $preview = TRUE;
            $item->set_preview(TRUE);
        }
        if ($servers->has_equal($item))
            $response = $responses[403];
        else {
            $priority = $preview? 1 : $priority ;
            $item->set_priority($priority, 'root'); 
            $res = $servers->queue_push($db, $item, TRUE, QUEUE_BOTTOM);
            if ($res !== FALSE) {
                inc_dl_lock($db, $arg_list[0]); // lock the dowload so it won't start until it is unlocked and all setdata is added to the article tabels
                $response = sprintf($responses[201], $item->get_id());
            } else 
                $response = $responses[402];
        }
    } else
        $response = $responses[501];
    return $response;
}


function queue_post(DatabaseConnection $db, server_data &$servers, $arg, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    return queue_generic($db, $servers, $username, COMMAND_START_POST, $arg, TRUE, $priority, FALSE);
}


function queue_prepare_post(DatabaseConnection $db, server_data &$servers, $arg, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    return queue_generic($db, $servers, $username, COMMAND_POST, $arg, TRUE, $priority, FALSE, TRUE, TRUE);
}


function queue_post_message(DatabaseConnection $db, server_data &$servers, $arg, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    return queue_generic($db, $servers, $username, COMMAND_POST_MESSAGE, $arg, TRUE, $priority, FALSE, TRUE, FALSE);
}


function queue_delete_set(DatabaseConnection $db, server_data &$servers, $arg, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    return queue_generic($db, $servers, $username, COMMAND_DELETE_SET, $arg, FALSE, $priority, FALSE);
}


function queue_delete_set_rss(DatabaseConnection $db, server_data &$servers, $arg, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    return queue_generic($db, $servers, $username, COMMAND_DELETE_SET_RSS, $arg, FALSE, $priority, FALSE);
}


function queue_merge_sets(DatabaseConnection $db, server_data &$servers, $arg, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    return queue_generic($db, $servers, $username, COMMAND_MERGE_SETS, $arg, FALSE, $priority, FALSE);
}


function queue_cleandir(DatabaseConnection $db, server_data &$servers, $arg, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    return queue_generic($db, $servers, $username, COMMAND_CLEANDIR, $arg, FALSE, $priority, FALSE);
}


function queue_cleandb(DatabaseConnection $db, server_data &$servers, $arg, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    return queue_generic($db, $servers, $username, COMMAND_CLEANDB, $arg, FALSE, $priority, FALSE, FALSE);
}


function queue_optimise(DatabaseConnection $db, server_data &$servers, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    return queue_generic($db, $servers, $username, COMMAND_OPTIMISE, '', FALSE, $priority, FALSE);
}


function queue_groups(DatabaseConnection $db, server_data &$servers, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    return queue_generic($db, $servers, $username, COMMAND_GROUPS, '', TRUE, $priority, TRUE); 
}


function queue_sendsetinfo(DatabaseConnection $db, server_data &$servers, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    global $responses;
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    $item = new action(COMMAND_SENDSETINFO, '', $username);
    if ($servers->has_equal($item))
        return $responses[403];
    $xmlrpc_mod = extension_loaded('xmlrpc');
    $curl_mod = extension_loaded('curl');
    if ($curl_mod === FALSE || $xmlrpc_mod === FALSE) {
        $err_str = '';
        if ($curl_mod === FALSE)
            $err_str = 'curl ';
        if ($xmlrpc_mod === FALSE)
            $err_str = 'xmlrpc';
        trim($err_str);
        return sprintf($responses[504], $err_str);
    }       

    return queue_generic($db, $servers, $username, COMMAND_SENDSETINFO, '', FALSE, $priority, FALSE);
}


function queue_gensets(DatabaseConnection $db, server_data &$servers, $arg_list, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    global $responses;
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    if (is_numeric($arg_list[0])) {
        $item = new action(COMMAND_GENSETS, $arg_list[0], $username);
        $item2 = new action(get_command(COMMAND_UPDATE), $arg_list[0], $username);
        $item3 = new action(get_command(COMMAND_PURGE), $arg_list[0], $username);
        $item4 = new action(get_command(COMMAND_EXPIRE), $arg_list[0], $username);
        if ($servers->has_equal($item) || $servers->has_equal($item2) || $servers->has_equal($item4) || $servers->has_equal($item4))
            $response = $responses[403];
        else {
            $res = $servers->queue_push($db, $item, TRUE);
            if ($res !== FALSE)
                $response = sprintf($responses[201], $item->get_id());
            else 
                $response = $responses[402];
        }
    } else if (strtolower($arg_list[0]) == 'all') 
        $response = queue_gensets_all($db, $servers, $username, $priority);
    else
        $response = $responses[501];
    return $response;
}


function queue_parse_nzb(DatabaseConnection $db, server_data &$servers, $arg_list, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    global $responses;
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    $url = $dlid = NULL;
    $start_time = 0;
    $last_idx = 0; 
    if (isset($arg_list[0])) {
        if (is_numeric($arg_list[0])) {
            $dlid = $arg_list[0];
            if (isset($arg_list[1])) {
                $url = $arg_list[1];
                $last_idx = 1;
            } else 
                $last_ixd = 0;
        } else {
            $url = $arg_list[0];
            $last_ixd = 0;
        }
    }
    if (isset($arg_list[$last_idx +1]) && is_numeric($arg_list[$last_idx+1])) {
        $start_time = $arg_list[$last_idx+1];
        if ($start_time < time()) 
            $start_time = 0;
    }
    if ($url !== NULL) {
        if ($dlid === NULL) {
            list($code, $dlid, $id) = do_create_download($db, $servers, $username, NULL, FALSE);
            if ($start_time == 0)
                set_start_time($db, $dlid, time());
            else {
                set_start_time($db, $dlid, $start_time);
                $item_unpause = new action (COMMAND_CONTINUE, get_command(COMMAND_DOWNLOAD) . " $dlid", $username, TRUE);
                $job = new job($item_unpause, $start_time, NULL); //try again in XX secs
                $servers->add_schedule($db, $job);
            }
            if ($code != 210) {
                $response = $responses[402];
                return $response;
            }
        }

        $item = new action(COMMAND_PARSE_NZB, "$dlid '{$url}'", $username);
        $res = $servers->queue_push($db, $item, TRUE);
        if ($res !== FALSE) {
            inc_dl_lock($db, $dlid); // lock the dowload so it won't start until it is unlocked and all setdata is added to the article tabels
            $response = sprintf($responses[201], $item->get_id());
        } else 
            $response = $responses[402];
    } else
        $response = $responses[501];
    return $response;
}


function queue_getsetinfo(DatabaseConnection $db, server_data &$servers, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    global $responses;
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    $item = new action(COMMAND_GETSETINFO, '', $username);
    if ($servers->has_equal($item))
        return $responses[403];
    $xmlrpc_mod = extension_loaded('xmlrpc');
    $curl_mod = extension_loaded('curl');
    if ($curl_mod === FALSE || $xmlrpc_mod === FALSE) {
        $err_str = '';
        if ($curl_mod === FALSE)
            $err_str = 'curl ';
        if ($xmlrpc_mod === FALSE)
            $err_str = 'xmlrpc';
        trim($err_str);
        return sprintf($responses[504], $err_str);
    }
    return queue_generic($db, $servers, $username, COMMAND_GETSETINFO, '', FALSE, $priority, FALSE);
}


function queue_check_version(DatabaseConnection $db, server_data &$servers, $username, $priority)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    return queue_generic($db, $servers, $username, COMMAND_CHECK_VERSION, '',  FALSE, $priority, FALSE);
}


function queue_purge_expire_all(DatabaseConnection $db, $cmd, server_data &$servers, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    global $responses;
    if ($cmd  == get_command_code(COMMAND_UPDATE_RSS) ||
        $cmd  == get_command_code(COMMAND_PURGE_RSS) || 
        $cmd  == get_command_code(COMMAND_EXPIRE_RSS))
        $query = "SELECT \"id\" AS \"ID\" FROM rss_urls WHERE \"subscribed\"='" . RSS_SUBSCRIBED ."'";
    else 
        $query = "SELECT \"ID\" FROM groups WHERE \"active\"='" . NG_SUBSCRIBED ."'";
    $res = $db->execute_query($query);
    $id_str = '';
    // queue each one
    if (is_array($res)) {
        $rv = TRUE;
        foreach ($res as $arr) {
            $item = new action($cmd, $arr['ID'], $username);
            if ($servers->has_equal($item))
                ; // what to do     $response = $responses[403];
            else {
                $rv = $servers->queue_push($db, $item, TRUE, QUEUE_BOTTOM, $priority);
                if ($rv === FALSE) 
                    break;
                $id_str .= "[{$item->get_id()}] ";
            }
        }
        if($rv === FALSE)
            $response = sprintf($responses[404], $id_str);
        else
            $response = sprintf($responses[202], $id_str);
    } else 
        $response = $responses[520];
    return $response;
}


function queue_gensets_all(DatabaseConnection $db, server_data &$servers, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    global $responses;
    // find all subsribed newsgroups 
    $query = "SELECT \"ID\" FROM groups WHERE \"active\"='" . NG_SUBSCRIBED ."'";
    $res = $db->execute_query($query);
    // queue each one
    $id_str = '';
    if (is_array($res)) {
        $rv = TRUE;
        foreach ($res as $arr) {
            $item = new action(get_command(COMMAND_GENSETS), $arr['ID'], $username);
            $item2 = new action(get_command(COMMAND_UPDATE), $arr['ID'], $username);
            $item3 = new action(get_command(COMMAND_EXPIRE), $arr['ID'], $username);
            $item4 = new action(get_command(COMMAND_PURGE), $arr['ID'], $username);
            if (!$servers->has_equal($item) && !$servers->has_equal($item2) && !$servers->has_equal($item3) && !$servers->has_equal($item4)) {
                $rv = $servers->queue_push($db, $item, TRUE, QUEUE_BOTTOM, $priority);
                if ($rv === FALSE) 
                    break;
                $id_str .= "[{$item->get_id()}] ";
            }
            else
                ; /// we do what now?
        }
        if($rv === FALSE)
            $response = sprintf($responses[404], $id_str);
        else
            $response = sprintf($responses[202], $id_str);
    } else
        $response = $responses[520];
    return $response;
}


function queue_update_all(DatabaseConnection $db, server_data &$servers, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    global $responses;
    // find all subsribed newsgroups 
    $query = "SELECT \"ID\" FROM groups WHERE \"active\"='" . NG_SUBSCRIBED ."'";
    $res = $db->execute_query($query);
    // queue each one
    $id_str = '';
    if (is_array($res)) {
        $rv = TRUE;
        foreach ($res as $arr) {
            $item = new action(get_command(COMMAND_UPDATE), $arr['ID'], $username);
            $item3 = new action(get_command(COMMAND_PURGE), $arr['ID'], $username);
            $item4 = new action(get_command(COMMAND_EXPIRE), $arr['ID'], $username);
            $item2 = new action(get_command(COMMAND_GENSETS), $arr['ID'], $username);
            if (!$servers->has_equal($item) && ! $servers->has_equal($item2) && !$servers->has_equal($item3) && !$servers->has_equal($item4)) {
                $rv = $servers->queue_push($db, $item, TRUE, QUEUE_BOTTOM, $priority);
                if ($rv === FALSE) 
                    break;
                $id_str .= "[{$item->get_id()}] ";
            }
            else
                ; /// we do what now?
        }
        if($rv === FALSE)
            $response = sprintf($responses[404], $id_str);
        else
            $response = sprintf($responses[202], $id_str);
    } else
        $response = $responses[520];
    return $response;
}


function queue_update_rss_all(DatabaseConnection $db, server_data &$servers, $username, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    global $responses;
    // find all subsribed newsgroups 
    $query = "SELECT \"id\" FROM rss_urls WHERE \"subscribed\"='" . RSS_SUBSCRIBED ."'";
    $res = $db->execute_query($query);
    // queue each one
    $id_str = '';
    if (is_array($res)) {
        $rv = TRUE;
        foreach ($res as $arr) {
            $item = new action(COMMAND_UPDATE_RSS, $arr['id'], $username);
            if (!$servers->has_equal($item)) {
                $rv = $servers->queue_push($db, $item, TRUE, QUEUE_BOTTOM, $priority);
                if ($rv === FALSE) 
                    break;
                $id_str .= "[{$item->get_id()}] ";
            }
            else
                ; /// we do what now?
        }
        if($rv === FALSE)
            $response = sprintf($responses[404], $id_str);
        else
            $response = sprintf($responses[202], $id_str);
    } else
        $response = $responses[520];
    return $response;
}


function queue_purge_expire(DatabaseConnection $db, $cmd, $arg_list, $username, server_data &$servers,$priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    global $responses;
    if (is_numeric($arg_list[0])) {
            $item = new action($cmd, $arg_list[0], $username);
            $item1 = new action(get_command(COMMAND_UPDATE), $arg_list[0], $username);
            $item3 = new action(get_command(COMMAND_PURGE), $arg_list[0], $username);
            $item4 = new action(get_command(COMMAND_EXPIRE), $arg_list[0], $username);
            $item2 = new action(get_command(COMMAND_GENSETS), $arg_list[0], $username);
        if ($servers->has_equal($item1) || $servers->has_equal($item2) || $servers->has_equal($item4)|| $servers->has_equal($item4))
            $response = $responses[403];
        else {
            $res = $servers->queue_push($db, $item, TRUE);
            if ($res !== FALSE)
                $response = sprintf($responses[201],$item->get_id());
            else 
                $response = $responses[402];
        }
    } else if (strtolower($arg_list[0]) == 'all') {
        // find all subsribed newsgroups 
        $response = queue_purge_expire_all($db, $cmd, $servers, $username, $priority);

    } else
        $response = $responses[501];
    return $response;
}


function queue_update_rss(DatabaseConnection $db, $cmd, $arg_list, $username, server_data &$servers,$priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    global $responses;
    if (is_numeric($arg_list[0])) {
        $item = new action($cmd, $arg_list[0], $username);
        if ($servers->has_equal($item))
            $response = $responses[403];
        else {
            $res = $servers->queue_push($db, $item, TRUE, QUEUE_BOTTOM, $priority);
            if ($res !== FALSE)
                $response = sprintf($responses[201], $item->get_id());
            else 
                $response = $responses[402];
        }
    } else if (strtolower($arg_list[0]) == 'all') 
        $response = queue_update_rss_all($db, $servers, $username, $priority);
    else
        $response = $responses[501];
    return $response;

}


function queue_update(DatabaseConnection $db, $cmd, $arg_list, $username, server_data &$servers,$priority=DEFAULT_PRIORITY)
{ 
    assert(is_numeric($priority) && $username != '');
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    global $responses;
    if (is_numeric($arg_list[0])) {
        $item = new action($cmd, $arg_list[0], $username);
        $item2 = new action(get_command(COMMAND_GENSETS), $arg_list[0], $username);
        $item3 = new action(get_command(COMMAND_PURGE), $arg_list[0], $username);
        $item4 = new action(get_command(COMMAND_EXPIRE), $arg_list[0], $username);
        if ($servers->has_equal($item) || $servers->has_equal($item2) ||$servers->has_equal($item3) || $servers->has_equal($item4))
            $response = $responses[403];
        else {
            $res = $servers->queue_push($db, $item, TRUE, QUEUE_BOTTOM, $priority);
            if ($res !== FALSE)
                $response = sprintf($responses[201], $item->get_id());
            else 
                $response = $responses[402];
        }
    } else if (strtolower($arg_list[0]) == 'all') 
        $response = queue_update_all($db, $servers, $username, $priority);
    else
        $response = $responses[501];
    return $response;
}


function queue_unpar_unrar(DatabaseConnection$db, $dir, $id, server_data &$servers, $username, $preview=FALSE, $priority=DEFAULT_PRIORITY)
{
    assert(is_numeric($priority) && is_bool($preview) && $username != '');
    global $responses;
    echo_debug_function(DEBUG_SERVER, __FUNCTION__);
    if (!is_numeric ($id))
        return $responses[501];
    $query = " \"destination\"FROM downloadinfo WHERE \"ID\"=$id";
    $res = $db->select_query($query, 1);
    if ($res === FALSE)
        return $responses[512];
    $upr = 0;

    $item = new action (COMMAND_UNPAR_UNRAR, "$id", $username);
    if ($dir == '' || $dir === NULL)
        $dir = $res[0]['destination'];
    $item->set_preview($preview);
    $item->set_dlpath($dir);
    $res = $servers->queue_push($db, $item, TRUE, QUEUE_BOTTOM, $priority);
    if ($res === FALSE) 
        return $responses[402];
    return $responses[200];
}


function queue_find_servers(DatabaseConnection$db, server_data &$servers, $arg_list, $username, $priority=DEFAULT_PRIORITY)
{
    global $config, $responses;
    if (!$servers->has_nntp_task())
        return $responses[401];
    if ($config['disable_nntp'] === TRUE) {
        return $responses[410];
    }
    $config['nntp_disable'] = TRUE;   // disable nntp so all other nntp actions will not be allowed
    try {
        $arg = isset( $arg_list[0]) ?  $arg_list[0] : '';
        $item = new action(COMMAND_FINDSERVERS, $arg, $username);
    } catch (exception $e) {
        return $responses[500]; // should not happen....
    }
    if ($servers->has_equal($item))
        return $responses[403];
    else {
        $res = $servers->queue_push($db, $item, TRUE, QUEUE_BOTTOM, $priority);
        if ($res === FALSE)
            return $responses[402];
    }
    return $responses[200];
}
?>
